package com.globopt.global;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.globopt.global.algorithm.Function;
import com.globopt.global.algorithm.Global;
import com.globopt.global.algorithm.Method;
import com.globopt.global.algorithm.Opts;
import com.globopt.global.algorithm.Unirandi;
import com.globopt.global.algorithm.functions.F1;
import com.globopt.global.algorithm.functions.F2;
import com.globopt.global.algorithm.functions.F3;
import com.globopt.global.algorithm.functions.F4;
import com.sun.istack.internal.logging.Logger;

/**
 * Servlet implementation class Calc
 */
@WebServlet("/Calc")
public class Calc extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private static final Logger logger = Logger.getLogger(Calc.class);

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public Calc() {
		super();
		// TODO Auto-generated constructor stub
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		request.setCharacterEncoding("utf-8");
		HttpSession session = request.getSession();
		response.setContentType("application/json; charset=utf-8");

		session.setAttribute("fun", request.getParameter("fun"));
		session.setAttribute("lb", request.getParameter("lb"));
		session.setAttribute("ub", request.getParameter("ub"));
		session.setAttribute("n", request.getParameter("n"));
		session.setAttribute("gammak", request.getParameter("gammak"));
		session.setAttribute("rk", request.getParameter("rk"));
		session.setAttribute("k", request.getParameter("k"));
		session.setAttribute("mfe", request.getParameter("mfe"));
		session.setAttribute("maxnlm", request.getParameter("maxnlm"));
		session.setAttribute("method", request.getParameter("method"));
		session.setAttribute("dsn", request.getParameter("dsn"));
		session.setAttribute("display", request.getParameter("display"));

		logger.info("function name: " + request.getParameter("fun"));
		logger.info("lb: " + request.getParameter("lb"));
		logger.info("ub: " + request.getParameter("ub"));
		logger.info("n: " + request.getParameter("n"));
		logger.info("gammak: " + request.getParameter("gammak"));
		logger.info("rk: " + request.getParameter("rk"));
		logger.info("k: " + request.getParameter("k"));
		logger.info("mfe: " + request.getParameter("mfe"));
		logger.info("maxnlm: " + request.getParameter("maxnlm"));
		logger.info("method: " + request.getParameter("method"));
		logger.info("dsn: " + request.getParameter("dsn"));
		logger.info("display: " + request.getParameter("display"));

		Function function;

		switch ((String) request.getParameter("fun")) {
		case "f1":
			function = new F1();
			break;
		case "f2":
			function = new F2();
			break;
		case "f3":
			function = new F3();
			break;
		case "f4":
			function = new F4();
			break;

		default:
			logger.info("Unexpected function name");
			function = new F1();
			break;
		}

		Opts opts = new Opts();

		opts.setN(Integer.parseInt((String) request.getParameter("n")));
		opts.setGammak(Double.parseDouble((String) request.getParameter("gammak")));
		opts.setRk(Double.parseDouble((String) request.getParameter("rk")));
		opts.setK(Integer.parseInt((String) request.getParameter("k")));
		opts.setMaximumFunctionEvaluation(Integer.parseInt((String) request.getParameter("mfe")));
		opts.setMaximumNumberOfLocalMinimum(Integer.parseInt((String) request.getParameter("maxnlm")));
		int directionSearchNumber = Integer.parseInt((String) request.getParameter("dsn"));
		Method method;
		if (request.getParameter("method").equals("Unirandi")) {
			method = new Unirandi(directionSearchNumber);
			opts.setMethod(method);
		} else {
			logger.info("Unexpected method name");
			method = new Unirandi(1000);
		}

		double[] lb = { -10.0, -10.0 };
		double[] ub = { 10.0, 10.0 };
		Global global = new Global(function, opts, lb, ub);

		global.calculate();

		logger.info("Number of minimum: " + global.getNumberOfMinimum());

		session.setAttribute("nc", global.getNumberOfMinimum());

		session.setAttribute("result", global.getResult());

		String destination = "calc.jsp";
		response.sendRedirect(response.encodeRedirectURL(destination));
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

	}

	public static String arrayToString(double[] a) {
		String ret = "<br>";
		for (int i = 0; i < a.length; i++) {
			if (a[i] != 0.0) {
				ret += String.format("%8f", a[i]) + "   ";
			}
		}
		return ret;
	}

	public static String arrayToString(double[][] a) {
		String ret = "<br>";
		for (int i = 0; i < a.length; i++) {
			for (int j = 0; j < a[0].length; j++) {
				if (a[i][j] != 0.0) {
					ret += String.format("%8f", a[i][j]) + "   ";
				}
			}
			ret += "<br>";
		}
		return ret;
	}
}
